// 现代 JavaScript Promise
// 作者：AI助手
// 最后更新：2024年

/**
 * Promise 是异步编程的基础
 * 特点：
 * 1. 状态：pending（进行中）、fulfilled（已成功）、rejected（已失败）
 * 2. 状态不可逆
 * 3. 链式调用
 * 4. 错误处理
 */

// 1. 基本 Promise 使用
// 1.1 创建 Promise
const simplePromise = new Promise((resolve, reject) => {
    // 模拟异步操作
    setTimeout(() => {
        const random = Math.random();
        if (random > 0.5) {
            resolve('成功！随机数: ' + random);
        } else {
            reject('失败！随机数太小: ' + random);
        }
    }, 1000);
});

// 1.2 使用 Promise
simplePromise
    .then(result => console.log('成功:', result))
    .catch(error => console.log('错误:', error))
    .finally(() => console.log('操作完成'));

// 2. Promise 链式调用
// 2.1 模拟用户数据获取
function fetchUserData(userId) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            const users = {
                1: { id: 1, name: '张三', email: 'zhangsan@example.com' },
                2: { id: 2, name: '李四', email: 'lisi@example.com' }
            };
            const user = users[userId];
            if (user) {
                resolve(user);
            } else {
                reject('用户不存在');
            }
        }, 1000);
    });
}

// 2.2 模拟获取用户订单
function fetchUserOrders(user) {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve({
                userId: user.id,
                orders: [
                    { id: 1, product: '手机', price: 5999 },
                    { id: 2, product: '电脑', price: 12999 }
                ]
            });
        }, 1000);
    });
}

// 2.3 链式调用示例
fetchUserData(1)
    .then(user => {
        console.log('获取到用户:', user);
        return fetchUserOrders(user);
    })
    .then(orders => {
        console.log('获取到订单:', orders);
    })
    .catch(error => {
        console.error('错误:', error);
    });

// 3. Promise 并行执行
// 3.1 Promise.all
const promise1 = Promise.resolve('第一个');
const promise2 = new Promise(resolve => setTimeout(() => resolve('第二个'), 1000));
const promise3 = new Promise(resolve => setTimeout(() => resolve('第三个'), 2000));

Promise.all([promise1, promise2, promise3])
    .then(results => {
        console.log('所有 Promise 完成:', results);
    })
    .catch(error => {
        console.error('某个 Promise 失败:', error);
    });

// 3.2 Promise.race
Promise.race([promise1, promise2, promise3])
    .then(result => {
        console.log('最快完成的 Promise:', result);
    });

// 3.3 Promise.allSettled
Promise.allSettled([
    Promise.resolve('成功'),
    Promise.reject('失败'),
    Promise.resolve('又成功')
])
    .then(results => {
        console.log('所有 Promise 的结果:', results);
    });

// 4. 实际应用示例
// 4.1 模拟 API 请求
class API {
    static get(url) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                if (url.includes('error')) {
                    reject(new Error('API 错误'));
                } else {
                    resolve({ data: '来自 ' + url + ' 的数据' });
                }
            }, 1000);
        });
    }
}

// 4.2 带重试的 Promise
function fetchWithRetry(url, maxRetries = 3) {
    return new Promise((resolve, reject) => {
        function attempt(retryCount) {
            API.get(url)
                .then(resolve)
                .catch(error => {
                    console.log(`尝试 ${retryCount}/${maxRetries} 失败`);
                    if (retryCount < maxRetries) {
                        attempt(retryCount + 1);
                    } else {
                        reject(error);
                    }
                });
        }
        attempt(1);
    });
}

// 4.3 带超时的 Promise
function withTimeout(promise, timeout) {
    const timeoutPromise = new Promise((_, reject) => {
        setTimeout(() => reject(new Error('操作超时')), timeout);
    });
    return Promise.race([promise, timeoutPromise]);
}

// 5. 最佳实践
// ✅ 始终添加错误处理
const goodPromise = new Promise((resolve, reject) => {
    // 异步操作
}).catch(error => {
    console.error('错误处理:', error);
});

// ✅ 使用 Promise.resolve/reject 快速创建 Promise
const immediatePromise = Promise.resolve('立即值');

// ✅ 在 Promise 链中正确传递数据
fetchUserData(1)
    .then(user => ({...user, timestamp: Date.now()}))
    .then(enrichedUser => console.log('处理后的用户:', enrichedUser));

// ❌ 避免嵌套 Promise
// badPromise.then(result => {
//     anotherPromise.then(result2 => { // 避免这样的嵌套
//         yetAnotherPromise.then(result3 => {
//             // 回调地狱
//         });
//     });
// });

// ❌ 避免忽略返回值
// promise.then(() => {
//     doSomething(); // 应该 return doSomething();
// }); 